/*
 $Id$

 Copyright (C) 2006-2007 by David Cotton

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
 Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package fr.free.jchecs.core.board;

import static fr.free.jchecs.core.PieceType.KING;
import fr.free.jchecs.core.Piece;
import fr.free.jchecs.core.Square;
import fr.free.jchecs.core.move.MoveGenerator;

/**
 * Skeleton of the implementation of a class representing a state of the game to
 * generate movements.
 * 
 * @author David Cotton
 */
abstract class AbstractMoveGenerator extends AbstractBoard implements
		MoveGenerator {
	private static final long serialVersionUID = -5319717726385658542L;

	/** The black king position. */
	private Square _blackKingSquare;

	/** Flag indicating if the black king castled. */
	private boolean _blackCastled;

	/** The white king position. */
	private Square _whiteKingSquare;

	/** Flag indicating if the white king castled. */
	private boolean _whiteCastled;

	/**
	 * Creates a new instance.
	 */
	protected AbstractMoveGenerator() {
		// Rien de spécifique...
	}

	/**
	 * Creates a new instance initialized from the state received.
	 * 
	 * @param pEtat
	 *            Original proceeding.
	 */
	protected AbstractMoveGenerator(final Board pEtat) {
		super(pEtat);

		for (final Square s : Square.values()) {
			final Piece p = pEtat.getPieceAt(s);
			if ((p != null) && (p.getType() == KING)) {
				setKingSquare(p.isWhite(), s);
			}
		}
	}

	/**
	 * Creates a new instance, copied from the received instance.
	 * 
	 * @param pEtat
	 *            Instance à copier.
	 */
	protected AbstractMoveGenerator(final AbstractMoveGenerator pEtat) {
		super(pEtat);

		_blackKingSquare = pEtat._blackKingSquare;
		_blackCastled = pEtat._blackCastled;
		_whiteKingSquare = pEtat._whiteKingSquare;
		_whiteCastled = pEtat._whiteCastled;
	}

	/**
	 * Reference box containing the king of a color.
	 * 
	 * @param pCouleur
	 *            Set to "true " if you search for the white king, to false
	 *            otherwise.
	 * @return Box containing the king.
	 */
	public Square getKingSquare(final boolean pCouleur) {
		if (pCouleur) {
			assert _whiteKingSquare != null;
			return _whiteKingSquare;
		}

		assert _blackKingSquare != null;
		return _blackKingSquare;
	}

	/**
	 * Indicates if the King has castled in color.
	 * 
	 * @param pBlanc
	 *            Set to "true " to get the status of whites.
	 * @return A "true" if the corresponding castled king.
	 */
	public final boolean isCastled(final boolean pBlanc) {
		if (pBlanc) {
			return _whiteCastled;
		}

		return _blackCastled;
	}

	/**
	 * Feeds the indicator having castled king for a color.
	 * 
	 * @param pBlanc
	 *            Set to "true" to feed the status of whites.
	 * @param pEtat
	 *            State indicator castling made ​​for color.
	 */
	protected final void setCastled(final boolean pBlanc, final boolean pEtat) {
		if (pBlanc) {
			_whiteCastled = pEtat;
		} else {
			_blackCastled = pEtat;
		}
	}

	/**
	 * Feeds the box containing the king of a color.
	 * 
	 * @param pCouleur
	 *            Set to "true" if one feeds the white king, to false otherwise.
	 * @param pCase
	 *            Box containing the king.
	 */
	protected final void setKingSquare(final boolean pCouleur,
			final Square pCase) {
		assert pCase != null;

		if (pCouleur) {
			_whiteKingSquare = pCase;
		} else {
			_blackKingSquare = pCase;
		}
	}
}
